//******************************************************************************
/**
 *
 * @file	pair_poke_st.c
 * @brief	連れ歩きポケモン　常駐関数
 * @author	saito
 * @data	07.02.14
 *
 * モジュール名：PairPoke_
 *
 */
//******************************************************************************
#include "common.h"
#include "fieldsys.h"
#include "fieldobj.h"

#include "mapdefine.h"
#include "ev_pokemon.h"
#include "pair_poke_st.h"

#include "pair_poke_idx.h"

#include "poke_follow_def.h"

#include "zonedata.h"
#include "savedata/pair_poke_data.h"

#include "pair_poke_humor.h"

#include "field/pair_poke_info.h"

#include "pair_poke_st.h"

///初期化、ロード時に立てるビット
#define PP_FLDOBJ_INIT_STA_BIT_ON \
(FLDOBJ_STA_BIT_ZONE_DEL_NOT|FLDOBJ_STA_BIT_HEIGHT_VANISH_OFF)
///初期化、ロード時に下ろすビット
#define PP_FLDOBJ_INIT_STA_BIT_OFF \
(FLDOBJ_STA_BIT_PAUSE_DIR|FLDOBJ_STA_BIT_PAUSE_ANM)

static void InitPairPokeWork(PAIR_POKE_INFO_WORK *work);
static void SetRareFlg(FIELD_OBJ_PTR fldobj, BOOL inRare);

static BOOL DhigudaCheck(const int inZone);
static void SetArcInfo(FIELD_OBJ_PTR fldobj, const int inMonsNo, const u8 inFormNo);
static FIELD_OBJ_PTR AddFieldOBJ( CONST_FIELD_OBJ_SYS_PTR fos,
		int monsno, u16 formno, int sex, int dir, int x, int z, const BOOL inRare );

//#define POKE_APP_DEBUG		//有効で、ボール格納してもポケが出現

//FLDOBJ_PARAM_1の使用状況
//1〜4bit目：アニメ速度		1bit
//5〜8bit目：浮遊		1bit
//9〜16bit目：大きいポケビット	1bit

//FLDOBJ_PARAM_2の使用状況
//1bit目：レア				1bit
//2bit目：バニッシュ		1bit
//3bit目：出現アニメフラグ	1bit
//9,10bit目：ジャンプ方向	2bit
//11bit〜16bit：アニメコマンド（最大がAC_WALK_R_2F	0x17なので足りる）


//--------------------------------------------------------------
/**
 * 初期化
 * @param	fos			CONST_FIELD_OBJ_SYS_PTR
 * @param	inX			追加するグリッドX座標
 * @param	inZ			追加するグリッドY座標
 * @param	inDir		初期方向 DIR_UP等
 * @param	inZoneID	ゾーンＩＤ
 *
 * @retval	FIELD_OBJ_PTR 連れ歩きポケモンのフィールドＯＢＪポインタ
 */
//--------------------------------------------------------------
FIELD_OBJ_PTR PairPoke_Init( CONST_FIELD_OBJ_SYS_PTR fos,
		const int inX, const int inZ, const int inDir, const int inZoneID)
{
	//ｆｓｙｓ取得
	FIELDSYS_WORK *fsys = FieldOBJSys_FieldSysWorkGet( fos );
	//手持ちパーティ取得
	POKEPARTY *my_party = SaveData_GetTemotiPokemon(fsys->savedata);
	int max = PokeParty_GetPokeCount(my_party);

	InitPairPokeWork(&fsys->PairPokeWork);

	//セーブデータ連れ歩き状態を連れ歩いていない状態に
	PairPokeDataSave_SetFollow(FLW_TYPE_NONE, PairPokeDataSave_GetSaveDataPtr(fsys->savedata));

	if (max != 0){
		POKEMON_PARAM *pp;
		int monsno;

		//パーティーからポケモンパラム取得
		if ( EvPoke_CountLivingPokemon(my_party)==0 ){
			//全滅してるときは、無条件で、先頭ポケモンを対象にする
			pp = EvPoke_GetPokemonTop(my_party);
		}else{
			//1匹でも残っている場合は、先頭からサーチする
			pp = EvPoke_GetLivingPokemonTop(my_party);
		}
		//モンスターナンバーを取得
		monsno = PokeParaGet(pp,ID_PARA_monsno,NULL);

		fsys->PairPokeWork.FldObj = NULL;

		//連れ歩けるかチェック
		if (PairPoke_CheckFollowable(monsno, inZoneID)){
			int rnd;
			int formno;
			int sex;
			u8 rare;
			//フォルムナンバーを取得
			formno = PokeParaGet(pp,ID_PARA_form_no,NULL);
			//性別を取得
			sex = PokeParaGet(pp,ID_PARA_sex,NULL);
			rare = PokeRareGet(pp);
			fsys->PairPokeWork.FldObj = AddFieldOBJ( fos, monsno, formno, sex, inDir, inX, inZ, rare );
			fsys->PairPokeWork.Follow = 1;
			//ｆｓｙｓに情報保存
			PairPoke_SetPokeInfoToWork( fsys, monsno, formno, rare, sex );
			//連れ歩きポケモン機嫌値初セット
			rnd = PokeParaGet(pp,ID_PARA_personal_rnd,NULL);
			PAIR_POKE_HUMOR_SetPoke(fsys->PairPokeHumor, pp, monsno, rnd);

			//主人公の形態により分岐
			{
				int player_form;
				player_form = Player_FormGet( fsys->player );
				//主人公が波乗り、自転車状態でない場合は、セーブデータの連れ歩き状態を連れ歩き状態にする
				if ((player_form == HERO_FORM_NORMAL)||(player_form == HERO_FORM_ROCKET)){		//通常
					PairPokeDataSave_SetFollow(FLW_TYPE_FLW, PairPokeDataSave_GetSaveDataPtr(fsys->savedata));
				}else if( player_form == HERO_FORM_CYCLE ){	//自転車
					PairPokeDataSave_SetFollow(FLW_TYPE_FLW_VANISH, PairPokeDataSave_GetSaveDataPtr(fsys->savedata));
					//連れ歩きポケモンを格納状態にする
					PairPoke_SetBallInState(fsys);
					//自転車状態なので、自機に重なって動くようにコードチェンジ
					FieldOBJ_MoveCodeChange( PairPoke_GetFldObjPtr(fsys), MV_PAIR_NO_RATE_CP_MV );
#ifdef POKE_APP_DEBUG
					PairPoke_SetVanishTalkFlg(PairPoke_GetFldObjPtr(fsys), FALSE);
					//↑ポケ表示自転車乗ってるときとかのポケの位置確認デバッグ用
#endif
				}else if( player_form == HERO_FORM_SWIM ){	//波乗り
					PairPokeDataSave_SetFollow(FLW_TYPE_FLW_VANISH, PairPokeDataSave_GetSaveDataPtr(fsys->savedata));
					//連れ歩きポケモンを格納状態にする
					PairPoke_SetBallInState(fsys);
					//自機に重なって動くようにコードチェンジ
					FieldOBJ_MoveCodeChange( PairPoke_GetFldObjPtr(fsys), MV_PAIR_NO_RATE_CP_MV );
				}else {
					GF_ASSERT(0);
				}
			}

			//出現禁止フラグが成立しているなら、非表示にする
			if ( PairPokeDataSave_GetForbidden(PairPokeDataSave_GetSaveDataPtr(fsys->savedata)) ){
				OS_Printf("現在連れポケ出現禁止中\n");
				PairPoke_SetBallInState(fsys);
			}
		}
	}

	return fsys->PairPokeWork.FldObj;
}

//--------------------------------------------------------------
/**
 * ロード
 *
 * 通信交換とかで先頭ポケの復帰が以下のパターンあります
 *
 *
 * A 連れ歩きをしていた　　　→　連れ歩きできなくなった
 * B 連れ歩きをしていた　　　→　連れ歩きできる
 * C 連れ歩きしていなかった　→　連れ歩きできるようになった
 * D 連れ歩きしていなかった　→　連れ歩きできない
 *
 * @param	fos			CONST_FIELD_OBJ_SYS_PTR
 * @param	inZoneID	ゾーンＩＤ
 *
 * @retval	FIELD_OBJ_PTR 連れ歩きポケモンのフィールドＯＢＪポインタ
 */
//--------------------------------------------------------------
void PairPoke_Load( CONST_FIELD_OBJ_SYS_PTR fos, const int inZoneID)
{
	//ｆｓｙｓ取得
	FIELDSYS_WORK *fsys = FieldOBJSys_FieldSysWorkGet( fos );
	//手持ちパーティ取得
	POKEPARTY *my_party = SaveData_GetTemotiPokemon(fsys->savedata);
	int max = PokeParty_GetPokeCount(my_party);

	InitPairPokeWork(&fsys->PairPokeWork);
	if (max != 0){
		//パーティーからポケモンパラム取得
		POKEMON_PARAM *pp = EvPoke_GetLivingPokemonTop(my_party);
		//モンスターナンバーを取得
		int monsno = PokeParaGet(pp,ID_PARA_monsno,NULL);
		int rnd = PokeParaGet(pp,ID_PARA_personal_rnd,NULL);

		//連れ歩きポケモン機嫌値初セット
		PAIR_POKE_HUMOR_SetPoke(fsys->PairPokeHumor, pp, monsno, rnd);

		//連れ歩けるかチェック
		if (PairPoke_CheckFollowable(monsno, inZoneID)){
			FIELD_OBJ_PTR fldobj;
			u8 sex;

			int formno;
			u8 rare;

			fldobj = FieldOBJSys_OBJIDSearch( fsys->fldobjsys, FLDOBJ_ID_POKE_PAIR );

			//連れ歩きいなかったけどWifiとかで交換して連れ歩きできるようになった場合を判定する
			if (fldobj == NULL){
				//パターンＣ
				OS_Printf("連れ歩きしていなかったけど交換とかで連れ歩くことになった\n");
				//リセットリクエスト
				fsys->PairPokeWork.NeedReset = 1;
				return;
			}

			//以降はパターンＢ

			//フォルムナンバーを取得
			formno = PokeParaGet(pp,ID_PARA_form_no,NULL);
			sex = PokeSexGet(pp);
			rare = PokeRareGet(pp);
			fsys->PairPokeWork.FldObj = fldobj;
			fsys->PairPokeWork.Follow = 1;

			//ｆｓｙｓに情報保存
			PairPoke_SetPokeInfoToWork( fsys, monsno, formno, rare, sex );
			//連れ歩きポケモン情報セット
			PairPoke_SetInfo(fldobj, monsno, formno, rare);

			//Wifi通信交換で、先頭のポケモンが入れ替わる可能性があるので、ここでコードをセットしなおす
			{
				//モンスターナンバーをOBJコードに変換
				int obj_code = PairPoke_GetObjCodeFromMonsNo(monsno, formno, sex);
				FieldOBJ_OBJCodeSet(fsys->PairPokeWork.FldObj, obj_code);
			}


			//主人公の形態により分岐
			{
				int player_form;
				player_form = Player_FormGet( fsys->player );
				//主人公が波乗り、自転車状態でない場合は、セーブデータの連れ歩き状態を連れ歩き状態にする
				if ((player_form == HERO_FORM_NORMAL)||(player_form == HERO_FORM_ROCKET)){		//通常
					PairPokeDataSave_SetFollow(FLW_TYPE_FLW, PairPokeDataSave_GetSaveDataPtr(fsys->savedata));
				}else if( player_form == HERO_FORM_CYCLE ){	//自転車
					PairPokeDataSave_SetFollow(FLW_TYPE_FLW_VANISH, PairPokeDataSave_GetSaveDataPtr(fsys->savedata));
					//バニッシュ状態を復帰
					PairPoke_SetVanishTalkFlg( fsys->PairPokeWork.FldObj, TRUE );
				}else if( player_form == HERO_FORM_SWIM ){	//波乗り
					PairPokeDataSave_SetFollow(FLW_TYPE_FLW_VANISH, PairPokeDataSave_GetSaveDataPtr(fsys->savedata));
					//バニッシュ状態を復帰
					PairPoke_SetVanishTalkFlg( fsys->PairPokeWork.FldObj, TRUE );
				}else {
					GF_ASSERT(0);
				}
			}
			if (PairPoke_GetVanishFlgPrm(fsys->PairPokeWork.FldObj)){
				//バニッシュ状態を復帰
				PairPoke_SetVanishTalkFlg( fsys->PairPokeWork.FldObj, TRUE );
			}
			//出現禁止フラグが成立しているなら、非表示にする
			if ( PairPokeDataSave_GetForbidden(PairPokeDataSave_GetSaveDataPtr(fsys->savedata)) ){
				OS_Printf("現在連れポケ出現禁止中\n");
				PairPoke_SetBallInState(fsys);
			}

			//自機との当たり判定無視ビットオン
			FieldOBJ_StatusBitSet_FellowHit( fsys->PairPokeWork.FldObj, FALSE );

			OS_Printf("連れ歩きポケモンを復帰\n");
		}else{
			//連れ歩きいたけどWifiとかで交換して連れ歩きでき無くなった場合を判定する
			FIELD_OBJ_PTR fldobj;
			fldobj = FieldOBJSys_OBJIDSearch( fsys->fldobjsys, FLDOBJ_ID_POKE_PAIR );
			//パターンＡ
			if (fldobj != NULL){
				u8 sex;
				int formno;
				u8 rare;
				OS_Printf("連れ歩きいたけど交換とかで連れ歩き出来なくなった\n");
				//フォルムナンバーを取得
				formno = PokeParaGet(pp,ID_PARA_form_no,NULL);
				sex = PokeSexGet(pp);
				rare = PokeRareGet(pp);

				//ｆｓｙｓに情報保存
				PairPoke_SetPokeInfoToWork( fsys, monsno, formno, rare, sex );
				//連れ歩きポケモン情報セット
				PairPoke_SetInfo(fldobj, monsno, formno, rare);
				//モンスターナンバーをOBJコードに変換
				{
					int obj_code = PairPoke_GetObjCodeFromMonsNo(monsno, formno, sex);
					FieldOBJ_OBJCodeSet(fldobj, obj_code);
				}
				fsys->PairPokeWork.FldObj = fldobj;
				//今まではいたのでFollowフラグをたててリセットリクエストする
				fsys->PairPokeWork.Follow = 1;
				//リセットリクエスト(ここでリクエストしてフィールドＯＢＪをデリートしてもらう)
				fsys->PairPokeWork.NeedReset = 1;

				return;
			}
			//パターンＤ
			//※交換とかで連れ歩き出来ない状態から連れ歩き出来ない状態への移行は何もしなくて良い
		}
	}
}

//--------------------------------------------------------------
/**
 * 連れ歩きポケモンのフィールドＯＢＪを取得
 *
 * @param	fsys			フィールドシステムポインタ
 *
 * @retval	FIELD_OBJ_PTR	フィールドＯＢＪポインタ
 */
//--------------------------------------------------------------
FIELD_OBJ_PTR PairPoke_GetFldObjPtr(FIELDSYS_WORK *fsys)
{
	return fsys->PairPokeWork.FldObj;
}

//--------------------------------------------------------------
/**
 * 連れ歩きポケモンのOBJコードを返す
 * @param	inMonsNo	モンスターナンバー
 * @param	inFormNo	フォルムナンバー
 * @param	inSex		性別
 * @retval	OBJコード
 */
//--------------------------------------------------------------
int PairPoke_GetObjCodeFromMonsNo(const int inMonsNo, const u16 inFormNo, const int inSex)
{
	int obj_code;
	if ( (inMonsNo<=0) || (MONSNO_END<inMonsNo) ){
		obj_code = PAIR_POKE_CODEORG;
	}else{
		obj_code = PAIR_POKE_CODEORG+PairPokeIdx_GetIdx(inMonsNo);
		//モンスターナンバーだけからだと不十分なので、ここからさらに調べる（フォルムとか）
		//性別による描き違いをして、かつ複数フォルムナンバー所持ポケモンはいないので、
		//性別違いをまずキーにして分岐
		if (PairPokeIdx_GetSexDif(inMonsNo)){		//性別による描き違いがある
			if(inSex == PARA_FEMALE ){ //メスの場合
				obj_code += 1;	//ベースから1シフトしたところがメスのコード
			}
		}else{		//性別による描き違いがない
			//フォルムを調べる
			int form;
			if ( inFormNo > PairPokeIdx_GetFormNum(inMonsNo) ){
				form = 0;
			}else{
				form = inFormNo;
			}
			obj_code += form;
		}
		//オーバーチェック
		if (obj_code > PAIR_POKE_CODE_END){
			obj_code = PAIR_POKE_CODEORG;
		}
	}

	return obj_code;
}

//--------------------------------------------------------------
/**
 * 連れ歩きポケモンの表示非表示
 * 通常のバニッシュとは異なり、
 * 自機の一歩で表示するようにする時に使用
 *
 * @param	fldobj	フィールドＯＢＪポインタ
 * @param	inFlg	バニッシュフラグ
 *
 * @retval	none
 */
//--------------------------------------------------------------
void PairPoke_StartVanish(FIELD_OBJ_PTR fldobj, const BOOL inFlg)
{
	PairPoke_SetVanishTalkFlg( fldobj, inFlg );
	if (inFlg){
		PairPoke_SetVanishFlgPrm(fldobj,1);
	}else{
		PairPoke_SetVanishFlgPrm(fldobj,0);
	}
}

//--------------------------------------------------------------
/**
 * パラメータセット バニッシュフラグ
 *
 * @param	fldobj	フィールドＯＢＪポインタ
 * @param	inFlg	バニッシュフラグ
 *
 * @retval	none
 */
//--------------------------------------------------------------
void PairPoke_SetVanishFlgPrm(FIELD_OBJ_PTR fldobj, const u8 inFlg)
{
	u8 low;
	u32 high;
	int param;
	param = FieldOBJ_ParamGet( fldobj, FLDOBJ_PARAM_2 );
	high = (param>>2);
	high = high << 2;
	low = (param & 0x1);	//１ビットマスク
	param = high | (inFlg<<1) | low;
	FieldOBJ_ParamSet( fldobj, param, FLDOBJ_PARAM_2 );
	OS_Printf("vnish_set_param2=%x\n",param);
}

//--------------------------------------------------------------
/**
 * パラメータ取得　バニッシュフラグ
 *
 * @param	fldobj	フィールドＯＢＪポインタ
 *
 * @retval	none
 */
//--------------------------------------------------------------
u8 PairPoke_GetVanishFlgPrm(CONST_FIELD_OBJ_PTR fldobj)
{
	u8 flg;
	int param;
	param = FieldOBJ_ParamGet( fldobj, FLDOBJ_PARAM_2 );
	flg = (param >> 1) & 0x1;
	return flg;
}

//--------------------------------------------------------------
/**
 * パラメータセット ジャンプ方向
 *
 * @param	fldobj	フィールドＯＢＪポインタ
 * @param	inDir	ジャンプ方向
 *
 * @retval	none
 */
//--------------------------------------------------------------
void PairPoke_SetJumpDirPrm(FIELD_OBJ_PTR fldobj, const u8 inDir)
{
	u8 low;
	u16 high;
	int param;
	param = FieldOBJ_ParamGet( fldobj, FLDOBJ_PARAM_2 );
	low = param & (0xff);		//8ビットマスク
	high = (param>>10);
	high = high << 10;
	param = high | (inDir<<8) |low;
	FieldOBJ_ParamSet( fldobj, param, FLDOBJ_PARAM_2 );
//	OS_Printf("ジャンプパラム%d\n",inDir);
	OS_Printf("jump_set_param2=%x\n",param);
}

//--------------------------------------------------------------
/**
 * パラメータセット アニメコマンド
 *
 * @param	fldobj	フィールドＯＢＪポインタ
 * @param	inCode	アニメコマンド
 *
 * @retval	none
 */
//--------------------------------------------------------------
void PairPoke_SetAnmCode(FIELD_OBJ_PTR fldobj, const u8 inCode)
{
	u8 low;
	u16 high;
	int param;

	GF_ASSERT(inCode <= AC_WALK_R_2F);

	param = FieldOBJ_ParamGet( fldobj, FLDOBJ_PARAM_2 );
	low = param & (0x3ff);	//10ビットマスク

	param = (inCode<<10) | low;
	FieldOBJ_ParamSet( fldobj, param, FLDOBJ_PARAM_2 );
	OS_Printf("cmd_set_param2=%x\n",param);
}

//--------------------------------------------------------------
/**
 * パラメータセット 出現アニメフラグ
 *
 * @param	fldobj	フィールドＯＢＪポインタ
 * @param	inFlg	0:出現アニメ不要　それ以外：出現アニメ必要
 *
 * @retval	none
 */
//--------------------------------------------------------------
void PairPoke_SetAppAnmPrm(FIELD_OBJ_PTR fldobj, const u8 inFlg)
{
	u8 low;
	u32 high;
	int param;
	param = FieldOBJ_ParamGet( fldobj, FLDOBJ_PARAM_2 );
	high = param >> 3;
	high = high <<3;
	low = (param & 0x3);	//２ビットマスク
	param = high | (inFlg<<2) | low;
	FieldOBJ_ParamSet( fldobj, param, FLDOBJ_PARAM_2 );
	OS_Printf("app_set_param2=%x\n",param);
}

//--------------------------------------------------------------
/**
 * パラメータ取得 出現アニメ有無
 *
 * @param	fldobj	フィールドＯＢＪポインタ
 *
 * @retval	u8		0:出現アニメ不要　それ以外：出現アニメ必要
 */
//--------------------------------------------------------------
u8 PairPoke_GetAppAnmPrm(CONST_FIELD_OBJ_PTR fldobj)
{
	u8 anm;
	int param;
	param = FieldOBJ_ParamGet( fldobj, FLDOBJ_PARAM_2 );
	anm = (param>>2)&(0x1);
	return anm;
}

//--------------------------------------------------------------
/**
 * パラメータ取得 ジャンプ方向
 *
 * @param	fldobj	フィールドＯＢＪポインタ
 *
 * @retval	u8		方向
 */
//--------------------------------------------------------------
u8 PairPoke_GetJumpDirPrm(CONST_FIELD_OBJ_PTR fldobj)
{
	u8 dir;
	int param;
	param = FieldOBJ_ParamGet( fldobj, FLDOBJ_PARAM_2 );
	dir = ((param>>8)&(0x3));//2ビットマスク
	return dir;
}

//--------------------------------------------------------------
/**
 * パラメータ取得 アニメコマンド
 *
 * @param	fldobj	フィールドＯＢＪポインタ
 *
 * @retval	u8		アニメコマンド
 */
//--------------------------------------------------------------
u8 PairPoke_GetAnmCode(CONST_FIELD_OBJ_PTR fldobj)
{
	u8 code;
	int param;
	param = FieldOBJ_ParamGet( fldobj, FLDOBJ_PARAM_2 );
	code = ((param>>10)&(0x3f));	//6ビットマスク
	return code;
}

//--------------------------------------------------------------
/**
 * 情報セット
 *
 * @param	fldobj		フィールドOBJポインタ
 * @param	inMonsNo	モンスターナンバー
 * @param	inFormNo	フォルムナンバー
 * @param	inRare		レアフラグ
 *
 * @return none
 */
//--------------------------------------------------------------
void PairPoke_SetInfo(FIELD_OBJ_PTR fldobj, const int inMonsNo, const u8 inFormNo, const BOOL inRare)
{
	//レア識別セット
	SetRareFlg( fldobj, inRare );
	//アーカイブ情報セット
	SetArcInfo( fldobj, inMonsNo, inFormNo );
	//モンスターナンバーセット
	FieldOBJ_ParamSet( fldobj, inMonsNo, FLDOBJ_PARAM_0 );
}

//--------------------------------------------------------------
/**
 * ビュー情報セット（ポケスロン石像専用）
 *
 * @param	fldobj		フィールドOBJポインタ
 * @param	inMonsNo	モンスターナンバー
 * @param	inFormNo	フォルムナンバー
 * @param	inRare		レアフラグ
 * @param	inObjCode	OBJコード
 *
 *  注意！：SetRareFlgで下位1bitにレアフラグが格納されるので1bit左シフトした値をinObjCode引数に渡すこと！
 *
 * @return none
 */
//--------------------------------------------------------------
void PairPoke_SetViewInfo(FIELD_OBJ_PTR fldobj, const int inMonsNo, const u8 inFormNo,
							const BOOL inRare, const int inObjCode)
{
	IWASAWA_PRINT("石像ObjCode SetViewInfo1 = %08x\n",inObjCode);
	//OBJCODEセット
	//SetRareFlgで下位1bitにレアフラグが格納されるので1bitシフトした値をinObjCode引数に渡すこと！
	FieldOBJ_ParamSet( fldobj, inObjCode, FLDOBJ_PARAM_2 );
	//レア識別セット
	SetRareFlg( fldobj, inRare );
	IWASAWA_PRINT("石像ObjCode SetViewInfo2 = %08x\n",FieldOBJ_ParamGet( fldobj, FLDOBJ_PARAM_2));

	//アーカイブ情報セット
	SetArcInfo( fldobj, inMonsNo, inFormNo );
	//モンスターナンバーセット
	FieldOBJ_ParamSet( fldobj, inMonsNo, FLDOBJ_PARAM_0 );
}

//--------------------------------------------------------------
/**
 * 連れ歩きポケモンの情報保存
 *
 * @param	fsys		フィールドシステムポインタ
 * @param	inMonsNo	モンスターナンバー
 * @param	inFormNo	フォルムナンバー
 * @param	inRare		レアフラグ
 * @param	inSex		性別
 *
 * @return none
 */
//--------------------------------------------------------------
void PairPoke_SetPokeInfoToWork(FIELDSYS_WORK *fsys,
								const int inMonsNo,
								const u8 inFormNo,
								const u8 inRare,
								const u8 inSex)
{
	fsys->PairPokeWork.MonsNo = inMonsNo;
	fsys->PairPokeWork.Rare = inRare;
	fsys->PairPokeWork.Form = inFormNo;
	fsys->PairPokeWork.Sex = inSex;
}

//--------------------------------------------------------------
/**
 * 連れ歩きポケモン情報をアーカイブから取得 大きいサイズか？
 * フォルムでサイズが変わらないことを前提としている
 *
 * @param	inMonsNo		モンスターナンバー
 *
 * @retval	u8     大きい　1　小さい　0
 */
//--------------------------------------------------------------
u8 PairPoke_GetInfoFromArc_BigSize(const int inMonsNo)
{
	PAIR_POKE_INFO info;
	int info_idx = PairPokeIdx_GetIdx(inMonsNo);
	ArchiveDataLoad(&info, ARC_PAIR_POKE_INFO, info_idx);
	return info.BigSize;
}

//--------------------------------------------------------------
/**
 * 連れ歩きポケモンのモンスターナンバーを返す
 *
 * @param	fldobj	フィールドＯＢＪポインタ
 *
 * @retval	int		モンスターナンバー
 */
//--------------------------------------------------------------
int PairPoke_GetMonsNo(CONST_FIELD_OBJ_PTR fldobj)
{
	return FieldOBJ_ParamGet( fldobj, FLDOBJ_PARAM_0 );
}

//--------------------------------------------------------------
/**
 * 連れ歩きポケモンがいるかをチェック
 *
 * @param	fsys			フィールドシステムポインタ
 *
 * @retval	BOOL		TRUE:いる	FALSE:いない
 */
//--------------------------------------------------------------
BOOL PairPoke_IsPairPoke(FIELDSYS_WORK *fsys)
{
	int num;
	POKEPARTY *my_party;
	if (!fsys->PairPokeWork.Follow){
		return FALSE;
	}
	my_party = SaveData_GetTemotiPokemon(fsys->savedata);
	num = EvPoke_CountLivingPokemon(my_party);
	if (num){
		return TRUE;
	}

	return FALSE;
}

//--------------------------------------------------------------
/**
 * 連れ歩きポケモンが存在するか(非表示の場合はいないとみなす)
 *
 * @param	fsys			フィールドシステムポインタ
 *
 * @retval	BOOL		TRUE:いる	FALSE:いない
 */
//--------------------------------------------------------------
BOOL PairPoke_IsVisible(FIELDSYS_WORK *fsys)
{
	if (PairPoke_IsPairPoke(fsys)){
		if ( FieldOBJ_StatusBitCheck_Vanish(fsys->PairPokeWork.FldObj) ){
			//連れ歩きいるけど非表示だからいないとする
			return FALSE;
		}
		return TRUE;		//連れ歩いていて、視覚的に確認できる
	}
	//連れ歩いていない
	return FALSE;
}


//--------------------------------------------------------------
/**
 * 1つ前のマップで現在のポケモンを連れ歩けるかをチェック
 * @param	fsys
 *
 * @retval	BOOL		TRUE:連れ歩いていた　FALSE:連れ歩いていない
 */
//--------------------------------------------------------------
BOOL PairPoke_CheckOldFollow(FIELDSYS_WORK *fsys)
{
	int old_zone = PairPokeDataSave_GetOldZone( PairPokeDataSave_GetSaveDataPtr(fsys->savedata) );
	return PairPoke_CheckFollowable(PairPoke_GetMonsNo(fsys->PairPokeWork.FldObj), old_zone);
}

//--------------------------------------------------------------
/**
 * 連れ歩けるかをチェック
 * @param	inMonsNo		モンスターナンバー
 * @param	inZoneID		ゾーンＩＤ
 *
 * @retval	BOOL		TRUE:連れ歩ける　FALSE:連れ歩けない
 */
//--------------------------------------------------------------
BOOL PairPoke_CheckFollowable(const int inMonsNo, const int inZoneID)
{
	u8 code;
	BOOL rc;

	//ディグダ・ダグトリオの連れ歩けない場所チェック
	if ( (inMonsNo == MONSNO_DHIGUDA)||(inMonsNo == MONSNO_DAGUTORIO) ){
		if ( !DhigudaCheck(inZoneID) ){
			return FALSE;
		}
	}
	//指定ゾーンの連れ歩きステートを取得
	code = ZoneData_GetPokeFollowCode(inZoneID);

	switch(code){
	case POKE_FOLLOW_NG:
		rc = FALSE;
		break;
	case POKE_FOLLOW_SMALL_OK:
		//連れ歩きポケモンが大きいポケモンか？
		if (PairPoke_GetInfoFromArc_BigSize(inMonsNo)){
			rc = FALSE;
		}else{
			rc = TRUE;
		}
		break;
	case POKE_FOLLOW_OK:
		rc = TRUE;
		break;
	}
	return rc;
}

//--------------------------------------------------------------
/**
 * 連れ歩きポケモンの表示状態と話しかけ可能状態をセット
 *
 * @param	fldobj		フィールドOBJポインタ
 * @param	inFlg		フラグ		TRUE:バニッシュ＆話しかけ不可		FALSE:表示＆話しかけ可
 *
 * @retval	none
 */
//--------------------------------------------------------------
void PairPoke_SetVanishTalkFlg(FIELD_OBJ_PTR fldobj, const BOOL inFlg)
{
	FieldOBJ_StatusBitSet_Vanish( fldobj, inFlg );
	FieldOBJ_StatusBitSet_TalkOFF( fldobj, inFlg );
}

//--------------------------------------------------------------
/**
 * 連れ歩きポケモン格納状態に
 *
 * @param	fsys		フィールドシステムポインタ
 *
 * @retval	none
 */
//--------------------------------------------------------------
void PairPoke_SetBallInState(FIELDSYS_WORK * fsys)
{
	FIELD_OBJ_PTR fldobj = fsys->PairPokeWork.FldObj;
	PairPoke_StartVanish(fldobj, TRUE);
	PairPoke_SetVanishFlgPrm(fldobj,0);//一歩移動で表示状態にならないように
}

//--------------------------------------------------------------
/**
 * 連れ歩きポケモンワーク初期化
 *
 * @param	PAIR_POKE_INFO_WORK
 *
 * @retval	none
 */
//--------------------------------------------------------------
static void InitPairPokeWork(PAIR_POKE_INFO_WORK *work)
{
	work->Follow = 0;
	work->FldObj = NULL;
	work->AnimeCommand = 0;
	work->Code = AC_NONE;
	work->GridX = 0;
	work->GridZ = 0;
	work->NeedReset = 0;
}

//--------------------------------------------------------------
/**
 * レア識別フラグセット
 *
 * @param	fldobj	フィールドＯＢＪポインタ
 * @param	inRare	レアフラグ
 *
 * @retval	none
 */
//--------------------------------------------------------------
static void SetRareFlg(FIELD_OBJ_PTR fldobj, BOOL inRare)
{
	int high;
	int param;
	param = FieldOBJ_ParamGet( fldobj, FLDOBJ_PARAM_2 );

	//1ビット目をクリア
	high = param >> 1;
	high = (high << 1);
	if (inRare){
		param = high | (1);
	}else{
		param = high;
	}
	FieldOBJ_ParamSet( fldobj, param, FLDOBJ_PARAM_2 );
	OS_Printf("rare_set_param2=%x\n",param);
}

//--------------------------------------------------------------
/**
 * ディグダを連れ歩けないゾーンチェック
 *
 * @param	inZone		ゾーン
 *
 * @retval	BOOL		TRUE:連れ歩ける FALSE:連れ歩けない
 */
//--------------------------------------------------------------
static BOOL DhigudaCheck(const int inZone)
{
	//鈴の塔は連れ歩けない
	switch(inZone){
	case ZONE_ID_D17R0101:
	case ZONE_ID_D17R0102:
	case ZONE_ID_D17R0103:
	case ZONE_ID_D17R0104:
	case ZONE_ID_D17R0105:
	case ZONE_ID_D17R0106:
	case ZONE_ID_D17R0107:
	case ZONE_ID_D17R0108:
	case ZONE_ID_D17R0109:
	case ZONE_ID_D17R0110:
	case ZONE_ID_D17R0112:
		return FALSE;
	}

	return TRUE;
}

//--------------------------------------------------------------
/**
 * 連れ歩きポケモン情報セット
 *
 * @param	fldobj	フィールドＯＢＪポインタ
 * @apram	inMonsNo	モンスターナンバー
 * @param	inFormNo	フォルムナンバー
 *
 * @retval	none
 */
//--------------------------------------------------------------
static void SetArcInfo(FIELD_OBJ_PTR fldobj, const int inMonsNo, const u8 inFormNo)
{
	PAIR_POKE_INFO info;
	u16 param;
	int info_idx = PairPokeIdx_GetIdx(inMonsNo);
	int form_num = PairPokeIdx_GetFormNum(inMonsNo);
	//別フォルムを持っているならオフセット計算する
	if ( form_num > 0 ){
		if (inFormNo <= form_num){
			info_idx+=inFormNo;
		}else{
			GF_ASSERT_MSG(0,"フォルムナンバー不正\n");
		}
	}
	ArchiveDataLoad(&info, ARC_PAIR_POKE_INFO, info_idx);

	param = (info.BigSize << 8)|(info.FlyFlg);
	FieldOBJ_ParamSet( fldobj, param, FLDOBJ_PARAM_1 );
}

#include "../fielddata/script/pair_scr_def.h"
//--------------------------------------------------------------
/**
 * 連れ歩きポケモンフィールドOBJ追加
 * @param	fos			FIELD_OBJ_SYS_PTR
 * @param	monsno		モンスターナンバー
 * @param	formno		フォルムナンバー
 * @param	sex			性別
 * @param	dir			方向
 * @param	x			グリッドX座標
 * @param	y			グリッドY座標
 * @param	inRare		レアフラグ
 * @retval	FIELD_OBJ_PTR
 */
//--------------------------------------------------------------
static FIELD_OBJ_PTR AddFieldOBJ( CONST_FIELD_OBJ_SYS_PTR fos,
		int monsno, u16 formno, int sex, int dir, int x, int z, const BOOL inRare )
{
	FIELD_OBJ_PTR fldobj;
	int obj;

	//モンスターナンバーをOBJコードに変換
	obj = PairPoke_GetObjCodeFromMonsNo(monsno, formno, sex);

	fldobj = FieldOBJ_AddHMake( fos, x, z, dir, obj, MV_PAIR, ZONE_ID_NOTHING );
	GF_ASSERT( fldobj != NULL && "player init obj add error" );

	FieldOBJ_OBJIDSet( fldobj, FLDOBJ_ID_POKE_PAIR );
	FieldOBJ_EventTypeSet( fldobj, 0 );
	FieldOBJ_EventFlagSet( fldobj, 0 );
	FieldOBJ_EventIDSet( fldobj, SCRID_PAIR_GS);

	//ワークを初期化（FLDOBJ_PARAM_0,FLDOBJ_PARAM_1は値がセットされるのでクリア省略）
	FieldOBJ_ParamSet( fldobj, 0, FLDOBJ_PARAM_2 );

	//連れ歩きポケモン情報セット
	PairPoke_SetInfo(fldobj, monsno, formno, inRare);

	FieldOBJ_MoveLimitXSet( fldobj, MOVE_LIMIT_NOT );
	FieldOBJ_MoveLimitZSet( fldobj, MOVE_LIMIT_NOT );
	FieldOBJ_StatusBit_ON( fldobj, PP_FLDOBJ_INIT_STA_BIT_ON );
	FieldOBJ_StatusBit_OFF( fldobj, PP_FLDOBJ_INIT_STA_BIT_OFF );
	FieldOBJ_StatusBitSet_HeightExpand( fldobj, TRUE );

	//とりあえず追加したときは、消しておく
	PairPoke_StartVanish(fldobj, TRUE);

	return fldobj;
}